package com.zym.init.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zym.init.core.exception.BannedException;
import com.zym.init.core.exception.ServiceException;
import com.zym.init.core.utils.ValidatorUtils;
import com.zym.init.enums.UserStatusEnum;
import com.zym.init.mapper.UserMapper;
import com.zym.init.model.dto.PageDTO;
import com.zym.init.model.po.UserPo;
import com.zym.init.model.query.UserQuery;
import com.zym.init.model.vo.UserVo;
import com.zym.init.service.RoleService;
import com.zym.init.service.UserService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Set;

import static com.zym.init.core.constant.CommonConstant.USER_ROLE;

/**
 * @author zouyangming
 * @description 针对表【user(用户表)】的数据库操作Service实现
 * @createDate 2023-10-15 16:46:17
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserPo> implements UserService {

    private final RoleService roleService;

    public UserServiceImpl(RoleService roleService) {
        this.roleService = roleService;
    }

    /**
     * 获取用户列表
     *
     * @param query 查询条件
     * @return 用户列表
     */
    @Override
    public PageDTO<UserVo> getPage(UserQuery query) {
        // 分页查询
        Page<UserPo> page = lambdaQuery()
                .eq(query.getUserId() != null, UserPo::getUserId, query.getUserId())
                .like(StringUtils.hasLength(query.getUsername()), UserPo::getUsername, query.getUsername())
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        // 封装返回
        return PageDTO.of(page, UserPo::toVo);
    }

    /**
     * 新增用户
     *
     * @param query 用户对象
     * @return 新增结果
     */
    @Override
    public boolean add(UserQuery query) {
        if (BeanUtil.isEmpty(query)) {
            return false;
        }
        if (selectUserByUsername(query.getUsername()) != null) {
            throw new ServiceException("用户已存在");
        }
        // 校验用户名和密码是否合法
        ValidatorUtils.checkUsername(query.getUsername());
        ValidatorUtils.checkPassword(query.getPassword());
        // 加密密码
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encryptedPassword = bCryptPasswordEncoder.encode(query.getPassword());
        // 新增用户
        UserPo newUserPo = new UserPo();
        newUserPo.setAvatar(query.getAvatar());
        newUserPo.setUsername(query.getUsername());
        newUserPo.setPassword(encryptedPassword);
        // 设置默认角色
        if (query.getRoleList() == null || query.getRoleList().isEmpty()) {
            newUserPo.setRoleList(Set.of(USER_ROLE));
        } else {
            newUserPo.setRoleList(query.getRoleList());
        }
        // 设置默认用户昵称
        if (!StringUtils.hasLength(query.getNickname())) {
            newUserPo.setNickname("用户" + DateUtil.date().toString("yyyyMMddHHmmss"));
        } else {
            newUserPo.setNickname(query.getNickname());
        }
        return this.save(newUserPo);
    }

    /**
     * 根据用户名查询用户
     *
     * @param username 用户名
     * @return 用户对象
     */
    @Override
    public UserPo selectUserByUsername(String username) {
        if (!StringUtils.hasLength(username)) {
            return null;
        }
        QueryWrapper<UserPo> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        UserPo userPo = this.getOne(wrapper);
        if (BeanUtil.isNotEmpty(userPo)) {
            return userPo;
        }
        return null;
    }

    /**
     * 检查当前用户是否已被封禁
     *
     * @param userId 用户id
     */
    @Override
    public void checkUserIsBanned(Long userId) {
        UserPo userPo = getById(userId);
        UserStatusEnum enumByStatus = UserStatusEnum.getEnumByStatus(userPo.getStatus());
        if (enumByStatus == UserStatusEnum.BANNED) {
            // 抛出封禁异常
            throw new BannedException();
        } else if (enumByStatus == UserStatusEnum.SUSPENDED) {
            // 获取当前时间距离解封时间的秒数
            long suspendedTime = DateUtil.between(DateUtil.date(), userPo.getSuspendedTime(), DateUnit.MINUTE);
            // 抛出异常
            throw new BannedException("账号已被封禁，距离解封还有：" + suspendedTime + "分钟");
        }
    }

    /**
     * 校验用户是否允许操作
     *
     * @param userPo 用户对象
     */
    @Override
    public void checkUserIsAllowed(UserPo userPo) {
        if (userPo.getUserId() == null || userPo.getUserId() != 1L) {
            throw new ServiceException("不允许操作默认超级管理员用户");
        }
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param username 用户名
     */
    @Override
    public void checkUsernameIsUnique(String username) {
        if (selectUserByUsername(username) != null) {
            throw new ServiceException("用户名已存在");
        }
    }

}




